package com.stack.knowyoubase.util;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSBuilder;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import com.stack.knowyoubase.config.AliYunOssConfig;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * 对象存储服务工具类
 *
 * @author stack
 */
@Component
public class AliYunOssUtil {

    @Resource
    private AliYunOssConfig aliYunOssConfig;

    /**
     * 上传文件
     *
     * @param file    文件
     * @param fileUrl 文件上传的路径
     * @return 服务器地址
     */
    public String upLoadFile(File file, String fileUrl) {
        String netWorkFileUrl = "";
        if (file == null) {
            return null;
        }
        OSSBuilder ossBuilder = new OSSClientBuilder();
        OSS ossClient = null;
        try {
            ossClient = ossBuilder.build(aliYunOssConfig.getEndpoint(), aliYunOssConfig.getAccessKeyId(), aliYunOssConfig.getAccessKeySecret());
            if (!ossClient.doesBucketExist(aliYunOssConfig.getBucketName())) {
                ossClient.createBucket(aliYunOssConfig.getBucketName());
                CreateBucketRequest createBucketRequest = new CreateBucketRequest(aliYunOssConfig.getBucketName());
                //权限设置为公共读
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }

            PutObjectResult putObjectResult = ossClient.putObject(new PutObjectRequest(aliYunOssConfig.getBucketName(), fileUrl, file));
            //权限设置为公共读
            ossClient.setBucketAcl(aliYunOssConfig.getBucketName(), CannedAccessControlList.PublicRead);
            if (putObjectResult != null) {
                //上传成功后路径
                netWorkFileUrl = "http://" + aliYunOssConfig.getBucketName() + "." + aliYunOssConfig.getEndpoint() + "/" + fileUrl;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return netWorkFileUrl;
    }

    public void downloadFile(String objectName, String localFileName) {
        OSSBuilder ossBuilder = new OSSClientBuilder();
        OSS ossClient = ossBuilder.build(aliYunOssConfig.getEndpoint(), aliYunOssConfig.getAccessKeyId(), aliYunOssConfig.getAccessKeySecret());
        ossClient.getObject(new GetObjectRequest(aliYunOssConfig.getBucketName(), objectName), new File(localFileName));
        ossClient.shutdown();

    }

    /**
     * 获取指定文件夹下的所有文件数量（分页）
     *
     * @param dir 文件夹名称
     */
    public Integer listFileCount(String dir) {
        OSSBuilder ossBuilder = new OSSClientBuilder();
        OSS ossClient = null;
        try {
            ossClient = ossBuilder.build(aliYunOssConfig.getEndpoint(), aliYunOssConfig.getAccessKeyId(), aliYunOssConfig.getAccessKeySecret());
            ListObjectsRequest listObjectsRequest = new ListObjectsRequest(aliYunOssConfig.getBucketName());
            //指定前缀
            listObjectsRequest.setPrefix(dir);
            //指定withMarker查询指定路径下的文件(解决多出一个文件夹的问题)
            String nextMarker = dir;
            ObjectListing objectListing = ossClient.listObjects(listObjectsRequest.withMarker(nextMarker));
            List<String> fileList = new ArrayList<>();
            for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
                fileList.add("http://" + aliYunOssConfig.getBucketName() + "." + aliYunOssConfig.getEndpoint() + "/" + objectSummary.getKey());
            }
            return fileList.size();
        } catch (Exception exception) {
            return 0;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 删除单个文件
     *
     * @param fileUrl 文件路径
     * @return 删除标记
     */
    public boolean deleteFile(String fileUrl) {
        OSSBuilder ossBuilder = new OSSClientBuilder();
        OSS ossClient = null;
        try {
            ossClient = ossBuilder.build(aliYunOssConfig.getEndpoint(), aliYunOssConfig.getAccessKeyId(), aliYunOssConfig.getAccessKeySecret());
            ossClient.deleteObject(aliYunOssConfig.getBucketName(), fileUrl);
            return true;
        } catch (Exception exception) {
            return false;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 分页获取指定文件夹下的所有文件（包含文件夹）
     *
     * @param dir 文件夹名称
     */
    public List<String> listPageFile(String dir, Integer page, Integer limit) {
        OSSBuilder ossBuilder = new OSSClientBuilder();
        OSS ossClient = null;
        try {
            ossClient = ossBuilder.build(aliYunOssConfig.getEndpoint(), aliYunOssConfig.getAccessKeyId(), aliYunOssConfig.getAccessKeySecret());
            ObjectListing objectListing = null;
            ListObjectsRequest listObjectsRequest = new ListObjectsRequest(aliYunOssConfig.getBucketName());
            //设定查询文件前缀（指定查询目录）
            listObjectsRequest.setPrefix(dir);
            // 设置正斜线（/）为文件夹的分隔符。
            listObjectsRequest.setDelimiter("/");
            //指定withMarker查询指定路径下的文件（解决查询出来的多一个空目录问题）
            String nextMarker = dir;
            //指定分页的条数，设置查询出文件的条数
            int maxKeys = limit;
            List<List<String>> fileLists = new ArrayList<>();
            do {
                objectListing = ossClient.listObjects(listObjectsRequest.withMarker(nextMarker).withMaxKeys(maxKeys));
                List<String> fileList = new ArrayList<>();
                for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
                    fileList.add("http://" + aliYunOssConfig.getBucketName() + "." + aliYunOssConfig.getEndpoint() + "/" + objectSummary.getKey());
                }
                for (String commonPrefix : objectListing.getCommonPrefixes()) {
                    fileList.add("http://" + aliYunOssConfig.getBucketName() + "." + aliYunOssConfig.getEndpoint() + "/" + commonPrefix);
                }
                fileLists.add(fileList);
                nextMarker = objectListing.getNextMarker();
            } while (objectListing.isTruncated());
            //返回分页查询结果
            if (fileLists != null && fileLists.size() >= page) {
                return fileLists.get(page - 1);
            } else {
                return null;
            }
        } catch (Exception exception) {
            return null;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }


}
